package com.mobile.service.impl;

import com.github.pagehelper.Page;
import com.itheima.common.constant.MessageConstant;
import com.itheima.common.constant.RedisMessageConstant;
import com.itheima.common.utils.SMSUtils;
import com.mobile.mapper.MemberMapper;
import com.mobile.mapper.OrderMapper;
import com.mobile.mapper.OrderSettingMapper;
import com.mobile.service.OrderService;
import com.mobile.pojo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Encounter
 * @date 2024/10/10 12:49<br/>
 */
@Service
@Slf4j
public class OrderServiceImpl implements OrderService
    {
        @Autowired
        private OrderMapper orderMapper;
        @Autowired
        private RedisTemplate redisTemplate;
        @Autowired
        private MemberMapper memberMapper;
        @Autowired
        private OrderSettingMapper orderSettingMapper;
        @Autowired
        private SMSUtils smsUtils;
        
        /**
         * 找到由id
         *
         * @param id id
         * @return {@link OderDetailVO }
         */
        @Override
        public OderDetailVO findById(Integer id)
            {
                return orderMapper.queryById(id);
            }
        
        /**
         * 预约
         *
         * @param reservationDTO 预留 DTO
         * @return int 剩余可预约数
         */
        @Override
        @Transactional
        public int reservation(ReservationDTO reservationDTO) throws ParseException
            {
                //获取当前手机号以及传入的验证码
                String telephone = reservationDTO.getTelephone();
                String validateCode = reservationDTO.getValidateCode();
                if (validateCode == null || telephone == null)
                    {
                        throw new RuntimeException(MessageConstant.TELEPHONE_VALIDATECODE_NOTNULL);
                    }
                //获取正确的验证码
                String key = RedisMessageConstant.SENDTYPE_ORDER + ":" + telephone;
                Long expire = redisTemplate.getExpire(key, TimeUnit.SECONDS);
                if (expire != null && expire > 0)
                    {
                        String code = (String) redisTemplate.opsForValue().get(key);
                        //判断验证码是否正确
                        if (code != null && !code.equals(validateCode))
                            {
                                //验证码错误，直接结束
                                log.error(MessageConstant.VALIDATECODE_ERROR);
                                throw new RuntimeException(MessageConstant.VALIDATECODE_ERROR);
                            }
                    }
                else
                    {
                        log.error(MessageConstant.TELEPHONE_VALIDATECODE_NOTNULL);
                        throw new RuntimeException(MessageConstant.TELEPHONE_VALIDATECODE_NOTNULL);
                    }
                
                //先查询当前会员是否已经在当天预约过
                //根据idCard查询当前会员id
                Map<String, Object> map = new HashMap<>();
                map.put("idCard", reservationDTO.getIdCard());
                List<Member> members = memberMapper.query(map);
                Member member = new Member();
                //判断查询结果是否为空
                if (members.isEmpty())
                    {
                        //用户不存在，自动完成注册
                        BeanUtils.copyProperties(reservationDTO, member);
                        member.setPhoneNumber(reservationDTO.getTelephone());
                        member.setRegTime(new Date());
                        memberMapper.insert(member);
                    }
                else
                    {
                        //idCard是唯一的，直接取第一个值即可
                        member = members.get(0);
                    }
                Integer memberId = member.getId();
                map.put("memberId", memberId);
                map.put("orderDate", reservationDTO.getOrderDate());
                map.put("setmealId", reservationDTO.getSetmealId());
                //查询是否已有未完成订单
                Page<OrderVO> page = orderMapper.query(map);
                List<OrderVO> result = page.getResult();
                if (result != null && !result.isEmpty())
                    {
                        OrderVO orderVO = result.get(0);
                        //当前订单已存在且未完成
                        if (!(orderVO == null || orderVO.getOrderStatus().equals(Order.ORDERSTATUS_CANCEL)))
                            {
                                log.error(MessageConstant.HAS_ORDERED);
                                throw new RuntimeException(MessageConstant.HAS_ORDERED);
                            }
                    }
                
                //订单不存在，查看是否有可预约名额
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                Date orderDate = dateFormat.parse(reservationDTO.getOrderDate());
                OrderSetting orderSetting = orderSettingMapper.queryByOrderDate(orderDate);
                if (orderSetting == null)
                    {
                        //当天未设置预约数，无法预约
                        log.error(MessageConstant.SELECTED_DATE_CANNOT_ORDER);
                        throw new RuntimeException(MessageConstant.SELECTED_DATE_CANNOT_ORDER);
                    }
                if ((orderSetting.getNumber() - orderSetting.getReservations()) > 0)
                    {
                        //剩余名额充足，开始新增
                        Order order = new Order();
                        //BeanUtils.copyProperties(reservationDTO, order);
                        order.setMemberId(memberId);
                        order.setOrderDate(orderDate);
                        order.setOrderType(Order.ORDERTYPE_WEIXIN);
                        order.setOrderStatus(Order.ORDERSTATUS_NO);
                        order.setSetmealId(Integer.valueOf(reservationDTO.getSetmealId()));
                        //插入数据
                        orderMapper.insert(order);
                        
                        //预约设置表
                        orderSetting.setReservations(orderSetting.getReservations() + 1);
                        orderSettingMapper.update(orderSetting);
                    }
                else
                    {
                        log.error(MessageConstant.ORDER_FULL);
                        throw new RuntimeException(MessageConstant.ORDER_FULL);
                    }
                
                //预约成功，发送通知消息
                String nameNick = member.getName();
                Map<String, String> noticeMap = new HashMap<>();
                noticeMap.put("name", nameNick);
                smsUtils.sendMessage(smsUtils.getOrderNotice(), reservationDTO.getTelephone(), noticeMap);
                
                //返回剩余可预约数
                return orderSetting.getNumber() - orderSetting.getReservations() - 1;
            }
    }
